import React, { useState, useEffect, useRef } from 'react'
import styles from './index.module.less'
import { cloneDeep } from 'lodash'
import classNames from 'classnames'

/**
 * 列表前面插入列表最后一项的图片，列表后面插入列表第一项的图片
 * 图片列表为 [1,2,3]  初始之后为 [3,1,2,3,1]
 * 图片点击下一张走nextPage，设置方向next
 * 当前索引为列表长度减一时，下一张的索引即为最大值（到达边界）
 * 当索引为等于列表的长度时 初始化成1 列表第一张的索引 取消动画，清空偏移量
 * 图片点击上一张走prevPage，设置方向prev
 * 当前索引为一时，上一张的索引即为最小值（到达边界）
 * 当索引为等于列表的长度时 初始化成1 列表最后一张的索引 取消动画，清空偏移量
 *
 * 监听当前索引
 * 当前索引不等于0并且方向为next的时候，恢复动画效果
 * 当前索引不等于0并且方向为prev的时候，恢复动画效果
 * 当索引等于列表长度时，并且方向为prev，取消动画
 * 当索引等于列表长度时，并且方向为next，取消动画
 *
 * 根据移动方向和索引处理边界情况 取消或开启动画
 * 图片的偏移量为负的索引 * 图片宽度
 *
 * 如果是先点击的左右箭头 在点击dot触发效果  则根据索引大小修改方向，修改当前偏移量
 * @param props
 * @returns {*}
 * @constructor
 */

const Carousel = (props) => {
	const { duration, autoPlay } = props
	const warpRef = useRef()
	const boxRef = useRef()
	const indexRef = useRef(1)
	const timerRef = useRef()

	const dataList = [1, 2, 3, 4, 5]

	const baseDistance = 500
	const [activeIndex, setActiveIndex] = useState(indexRef.current)
	const [direction, setDirection] = useState('next')
	const [initFlag, setInitFlag] = useState(true)
	const [isRunning, setIsRunning] = useState(false)
	const [dotClick, setDotClick] = useState(false)

	useEffect(() => {
		if (boxRef.current && duration) {
			const target = boxRef.current
			// target.style.transition = `all ${duration}s linear`
			target.style.transform = `translateX(${-baseDistance}px)`
			setInitFlag(false)
		}
	}, [duration, boxRef])

	useEffect(() => {
		if (!initFlag) {
			const target = boxRef.current
			target.style.transition = `all ${duration}s linear`
		}
	}, [initFlag])

	useEffect(() => {
		if (autoPlay) {
			autoPlayFn()
		}
	}, [autoPlay])

	const autoPlayFn = () => {
		timerRef.current = setInterval(() => {
			nextPage()
		}, (duration + 0.1) * 1000)
	}

	const nextPage = () => {
		if (isRunning) return
		setIsRunning(() => true)
		setDotClick(() => false)

		const target = boxRef.current
		let targetIndex
		if (indexRef.current === dataList.length) {
			targetIndex = 0
			if (direction === 'prev') {
				target.style.transition = 'none'
				target.style.transform = `translateX(0px)`
				targetIndex = 1
			}
		} else {
			targetIndex = indexRef.current + 1
		}
		indexRef.current = targetIndex
		setActiveIndex(indexRef.current)
		setDirection('next')
	}

	const prevPage = () => {
		if (isRunning) return
		setIsRunning(() => true)
		setDotClick(() => false)
		const target = boxRef.current
		let targetIndex
		if (activeIndex === 0) {
			targetIndex = dataList.length
			if (direction === 'next') {
				target.style.transition = 'none'
				target.style.transform = `translateX(${-dataList.length * baseDistance}px)`
				targetIndex = dataList.length - 1
			}
		} else {
			targetIndex = activeIndex - 1
		}
		indexRef.current = targetIndex
		setActiveIndex(indexRef.current)
		setDirection('prev')
	}

	useEffect(() => {
		if (isRunning) {
			setTimeout(() => {
				setIsRunning(() => false)
			}, duration * 1000)
		}
	}, [isRunning])

	useEffect(() => {
		if (dotClick && indexRef.current === dataList.length) return
		if (initFlag) return
		let moveDistance
		moveDistance = -indexRef.current * baseDistance
		const target = boxRef.current

		if (indexRef.current !== 0 && direction === 'next') {
			target.style.transition = `all ${duration}s linear`
		}

		if (indexRef.current !== 0 && direction === 'prev') {
			target.style.transition = `all ${duration}s linear`
		}

		if (indexRef.current === dataList.length && direction === 'prev') {
			target.style.transition = `none`
		}

		target.style.transform = `translateX(${moveDistance}px)`

		if (direction === 'next' && indexRef.current === dataList.length) {
			setTimeout(() => {
				target.style.transition = 'none'
				target.style.transform = `translateX(0px)`
				// setActiveIndex(0)
				indexRef.current = 0
				setActiveIndex(indexRef.current)
			}, duration * 1000)
		}

		if (direction === 'prev' && indexRef.current === 0) {
			setTimeout(() => {
				target.style.transition = 'none'
				target.style.transform = `translateX(${-dataList.length * baseDistance}px)`
				// setActiveIndex(dataList.length)
				indexRef.current = dataList.length
				setActiveIndex(indexRef.current)
			}, duration * 1000)
		}
	}, [indexRef.current])

	const dotChange = (index) => {
		if (isRunning) return
		setIsRunning(() => true)
		setDotClick(() => true)
		if (index === activeIndex) return
		if (index === 1 && activeIndex === dataList.length) {
			const target = boxRef.current
			target.style.transform = `translateX(${-dataList.length * baseDistance}px)`
			setDirection('prev')
			// setActiveIndex(index)
			indexRef.current = index
			setActiveIndex(indexRef.current)
		}
		if (index !== dataList.length) {
			// setActiveIndex(index)
			indexRef.current = index
			setActiveIndex(indexRef.current)
		}
		if (index === dataList.length) {
			const target = boxRef.current
			target.style.transform = `translateX(${-dataList.length * baseDistance}px)`
			// setActiveIndex(index)
			indexRef.current = index
			setActiveIndex(indexRef.current)
		}
	}

	const mouseenter = (e) => {
		e.preventDefault()
		clearInterval(timerRef.current)
		timerRef.current = null
	}

	const mouseleave = (e) => {
		e.preventDefault()
		autoPlayFn()
	}

	return (
		<div>
			<div>当前是第{activeIndex}页</div>
			<div className={styles.wrap} ref={warpRef} onMouseEnter={mouseenter} onMouseLeave={mouseleave}>
				<div className={styles.outBox}>
					<div className={styles.box} ref={boxRef}>
						<div className={classNames(styles.item, styles[`item${dataList.length - 1}`])}>{dataList.length}</div>
						{dataList.map((i, t) => {
							return (
								<div key={t} className={classNames(styles.item, styles[`item${t}`])}>
									{i}
								</div>
							)
						})}
						<div className={classNames(styles.item, styles[`item0`])}>1</div>
					</div>
				</div>
				<div className={styles.btnBox}>
					<button onClick={prevPage} className={styles.btn}>
						上一张
					</button>
					<button onClick={nextPage} className={styles.btn}>
						下一张
					</button>
				</div>
				<div className={styles.dotsBox}>
					<div className={styles.dot} onClick={() => dotChange(1)}>
						1
					</div>
					<div className={styles.dot} onClick={() => dotChange(2)}>
						2
					</div>
					<div className={styles.dot} onClick={() => dotChange(3)}>
						3
					</div>
					<div className={styles.dot} onClick={() => dotChange(4)}>
						4
					</div>
					<div className={styles.dot} onClick={() => dotChange(5)}>
						5
					</div>
				</div>
			</div>
		</div>
	)
}

Carousel.defaultProps = {
	duration: 1,
	autoPlay: true,
}

export default Carousel
